package com.b2b.controller;

import com.alibaba.fastjson.JSONObject;
import com.b2b.exception.CustomException;
import com.b2b.exception.CustomUnauthorizedException;
import com.b2b.model.CompanyUserRoleDto;
import com.b2b.model.InfoDto;
import com.b2b.model.UserDto;
import com.b2b.model.common.BaseDto;

import com.b2b.model.common.Constant;
import com.b2b.model.common.ResponseBean;
import com.b2b.model.entity.SMS;
import com.b2b.model.entity.User;

import com.b2b.service.CompanyUserRoleService;
import com.b2b.service.UserService;
import com.b2b.util.*;
import com.b2b.util.common.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * UserController
 * @author dolyw.com
 * @date 2018/8/29 15:45
 */
@RestController
@RequestMapping("/user")
@PropertySource("classpath:config.properties")
public class UserController {

    /**
     * RefreshToken过期时间
     */
    @Value("${refreshTokenExpireTime}")
    private String refreshTokenExpireTime;

    private final UserUtil userUtil;

    private final CompanyInfoUtil companyInfoUtil;

    private final UserService userService;

    private final CompanyUserRoleService companyUserRoleService;

    @Autowired
    public UserController(UserUtil userUtil, UserService userService, CompanyUserRoleService companyUserRoleService,
                          CompanyRoleUtil companyRoleUtil,CompanyInfoUtil companyInfoUtil) {
        this.userUtil = userUtil;
        this.userService = userService;
        this.companyUserRoleService = companyUserRoleService;
        this.companyInfoUtil = companyInfoUtil;
    }


    @GetMapping("/get")
    // 公司
//    @RequiresPermissions(logical = Logical.AND, value = {"user:view"})
    public ResponseBean user(InfoDto infoDto) {
        Integer companyId = infoDto.getId();
        if (infoDto.getPage() == null || infoDto.getRows() == null) {
            infoDto.setPage(1);
            infoDto.setRows(10);
        }
        PageHelper.startPage(infoDto.getPage(), infoDto.getRows());
        List<User> users = userUtil.getUserByCompanyId(companyId);
        PageInfo<User> selectPage = new PageInfo<>(users);
        if (users == null) {
            throw new CustomException("查询失败(Query Failure)");
        }
        Map<String, Object> result = new HashMap<>(16);
        result.put("count", selectPage.getTotal());
        result.put("data", selectPage.getList());
        return new ResponseBean(HttpStatus.OK.value(), "查询成功(Query was successful)", result);
    }


    /**
     * 获取用户列表
     *
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author dolyw.com
     * @date 2018/8/30 10:41
     */
    @GetMapping
//    @RequiresPermissions(logical = Logical.AND, value = {"user:view"})
    public ResponseBean user(@Validated BaseDto baseDto) {
        if (baseDto.getPage() == null || baseDto.getRows() == null) {
            baseDto.setPage(1);
            baseDto.setRows(10);
        }
        PageHelper.startPage(baseDto.getPage(), baseDto.getRows());
        List<User> users = userService.selectAll();
        PageInfo<User> selectPage = new PageInfo<User>(users);
        if (users == null) {
            throw new CustomException("查询失败(Query Failure)");
        }
        Map<String, Object> result = new HashMap<String, Object>(16);
        result.put("count", selectPage.getTotal());
        result.put("data", selectPage.getList());
        return new ResponseBean(HttpStatus.OK.value(), "查询成功(Query was successful)", result);
    }


    /**
     * @param
     * @return
     */
    @PostMapping("/login")
    public ResponseBean login(@RequestBody UserDto userDto, HttpServletResponse httpServletResponse) {
        String userName = userDto.getUserName();
        User userTemp = new User();
        CompanyUserRoleDto companyUserRoleDto = new CompanyUserRoleDto();
        userTemp.setUserName(userName);
        if (userService.selectCount(userTemp) == 0) {
            throw new CustomException("账号不存在(Query Failure)");
        }
        userTemp = userService.selectOne(userTemp);
        if (!(userTemp.getPassword().equals(userDto.getPassword()))) {
            throw new CustomException("密码错误(Query Failure)");
        }
        Integer id = userTemp.getUserId();

        companyUserRoleDto.setUserId(id);
        CompanyUserRoleDto companyUserRoleDtoTemp = companyUserRoleService.selectOne(companyUserRoleDto);
        Integer companyId = companyUserRoleDtoTemp.getCompanyId();

//        String key = AesCipherUtil.deCrypto(userDtoTemp.getPassword());
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        String token = JwtUtil.sign(userTemp.getPhone(), currentTimeMillis);
        JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + userTemp.getPhone(), currentTimeMillis, Integer.parseInt(refreshTokenExpireTime));
        httpServletResponse.setHeader("Authorization", token);
        httpServletResponse.setHeader("Acc ess-Control-Expose-Headers", "Authorization");

        User user = userService.selectByPrimaryKey(id);
        if (companyId == null) {
            return new ResponseBean(HttpStatus.OK.value(), "登录成功(Query was successful)", user);
        } else {
//            Integer roleId = companyUserRoleDtoTemp.getRoleId();
//            JSONObject roleList = companyRoleUtil.getRole(roleId);
//            JSONObject route = new JSONObject();
//            for (int i = 0; i < roleList.size(); i++) {
//                route.put(String.valueOf(i), companyRouteAuthorityUtil.getRoutePath(Integer.parseInt(roleList.getString(String.valueOf(i)))));
//            }
            JSONObject login = new JSONObject();
//            String userinfo = JSONObject.toJSONString(user);
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userId", user.getUserId());
            userInfo.put("userName", user.getUserName());
            userInfo.put("companyId", companyId);
            userInfo.put("companyName",companyInfoUtil.getCompanyName(companyId));
            userInfo.put("headerImg", user.getImgUrl());
            userInfo.put("hasCompanyCertification", true);
            String[] perms = new String[]{
                    "/shoppingCart",
                    "/orderGenerate",
                    "/message",
                    "/setting",
                    "/setting/home",
                    "/setting/accountSecurity",
                    "/setting/receivingAddress",
                    "/setting/personalAuthentication",
                    "/setting/companyAuthentication",
                    "/seller",
                    "/seller/home",
                    "/seller/goodsManage",
                    "/seller/goodsManage/goodsOnSale",
                    "/seller/goodsManage/goodsNotOnShelf",
                    "/seller/goodsManage/goodsAdd",
                    "/seller/orderManage",
                    "/seller/orderManage/goodsSold",
                    "/seller/orderManage/service",
                    "/seller/orderManage/evaluate",
                    "/seller/orderManage/inquiry",
                    "/seller/orderManage/bidding",
                    "/seller/contractManage",
                    "/seller/contractManage/masterOrder",
                    "/seller/contractManage/contractTemplate",
                    "/seller/companyManage",
                    "/seller/companyManage/companyInfo",
                    "/seller/companyManage/shopManage",
                    "/seller/companyManage/roleManage",
                    "/seller/companyManage/employeeManage",
                    "/seller/statisticalReport",
                    "/seller/statisticalReport/sale",
                    "/seller/statisticalReport/goods",
                    "/seller/statisticalReport/flow",
                    "/seller/statisticalReport/customer ",
                    "/buyer",
                    "/buyer/home",
                    "/buyer/order",
                    "/buyer/evaluate",
                    "/buyer/service",
                    "/buyer/shoppingCart",
                    "/buyer/history",
                    "/buyer/goodsCollection",
                    "/buyer/inquiry",
                    "/buyer/bidding",
                    "/buyer/wallet",
                    "/buyer/contractManage",
                    "/buyer/contractManage/masterOrder",
                    "/buyer/contractManage/contractTemplate",
                    "/buyer/intervention",
                    "/:catchAll(.*)"
            };
            login.put("userInfo", userInfo);
            login.put("perms", perms);
            login.put("token", token);
            return new ResponseBean(HttpStatus.OK.value(), "登录成功(Query was successful)", login);
        }
    }

    @PostMapping("/login/sendSMS")
    public ResponseBean loginSendSMS(HttpServletRequest request, @RequestBody SMS sms) {
        String phone = sms.getPhone();
        Integer min = 3;
        sms.setMin(min);
        sms.setTemplateId(1109983);
        if (phone == null || phone.equals("")) {
            throw new CustomUnauthorizedException("号码为空(Phone Null.)");
        }
        User userTemp = new User();
        userTemp.setPhone(phone);
        userTemp = userService.selectOne(userTemp);
        assert userTemp != null;
        if (userTemp.getUserName().equals("")) {
            throw new CustomUnauthorizedException("该帐号不存在(Phone exist.)");
        }
        String s = SMSUtil.sendSMS(request, sms);
        return new ResponseBean(HttpStatus.OK.value(), "发送成功(Send Success)", s);
    }

    @PostMapping("/login/checkSMS")
    public ResponseBean loginCheckSMS(@RequestBody SMS sms, HttpServletRequest request, HttpServletResponse httpServletResponse) {
        SMSUtil.checkSMS(sms);
        String phone = sms.getPhone();
        User userTemp = new User();
        CompanyUserRoleDto companyUserRoleDto = new CompanyUserRoleDto();
        userTemp.setPhone(phone);
        userTemp = userService.selectOne(userTemp);
        if (userTemp == null) {
            throw new CustomException("账号不存在(Query Failure)");
        }
        Integer id = userTemp.getUserId();

        companyUserRoleDto.setUserId(id);
        CompanyUserRoleDto companyUserRoleDtoTemp = companyUserRoleService.selectOne(companyUserRoleDto);
        Integer companyId = companyUserRoleDtoTemp.getCompanyId();

//        String key = AesCipherUtil.deCrypto(userDtoTemp.getPassword());
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        String token = JwtUtil.sign(sms.getPhone(), currentTimeMillis);
        httpServletResponse.setHeader("Authorization", token);
        httpServletResponse.setHeader("Acc ess-Control-Expose-Headers", "Authorization");

        User user = userService.selectByPrimaryKey(id);
        if (companyId == null) {
            return new ResponseBean(HttpStatus.OK.value(), "登录成功(Query was successful)", user);
        } else {

            JSONObject login = new JSONObject();
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userName", user.getUserName());
            userInfo.put("companyId", companyId);
            userInfo.put("companyName",companyInfoUtil.getCompanyName(companyId));
            userInfo.put("headerImg", user.getImgUrl());
            userInfo.put("hasCompanyCertification", true);
            String[] perms = new String[]{
                    "/shoppingCart",
                    "/orderGenerate",
                    "/message",
                    "/setting",
                    "/setting/home",
                    "/setting/accountSecurity",
                    "/setting/receivingAddress",
                    "/setting/personalAuthentication",
                    "/setting/companyAuthentication",
                    "/seller",
                    "/seller/home",
                    "/seller/goodsManage",
                    "/seller/goodsManage/goodsOnSale",
                    "/seller/goodsManage/goodsNotOnShelf",
                    "/seller/goodsManage/goodsAdd",
                    "/seller/orderManage",
                    "/seller/orderManage/goodsSold",
                    "/seller/orderManage/service",
                    "/seller/orderManage/evaluate",
                    "/seller/orderManage/inquiry",
                    "/seller/orderManage/bidding",
                    "/seller/contractManage",
                    "/seller/contractManage/masterOrder",
                    "/seller/contractManage/contractTemplate",
                    "/seller/companyManage",
                    "/seller/companyManage/companyInfo",
                    "/seller/companyManage/shopManage",
                    "/seller/companyManage/roleManage",
                    "/seller/companyManage/employeeManage",
                    "/seller/statisticalReport",
                    "/seller/statisticalReport/sale",
                    "/seller/statisticalReport/goods",
                    "/seller/statisticalReport/flow",
                    "/seller/statisticalReport/customer ",
                    "/buyer",
                    "/buyer/home",
                    "/buyer/order",
                    "/buyer/evaluate",
                    "/buyer/service",
                    "/buyer/shoppingCart",
                    "/buyer/history",
                    "/buyer/goodsCollection",
                    "/buyer/inquiry",
                    "/buyer/bidding",
                    "/buyer/wallet",
                    "/buyer/contractManage",
                    "/buyer/contractManage/masterOrder",
                    "/buyer/contractManage/contractTemplate",
                    "/buyer/intervention",
                    "/:catchAll(.*)"
            };
            login.put("userInfo", userInfo);
            login.put("perms", perms);
            login.put("token", token);
            return new ResponseBean(HttpStatus.OK.value(), "登录成功(Query was successful)", login);
        }
    }

    /**
     * 测试登录
     *
     * @param
     * @return com.wang.model.common.ResponseBean
     * @author dolyw.com
     * @date 2018/8/30 16:18
     */
    @GetMapping("/article")
    public ResponseBean article() {
        Subject subject = SecurityUtils.getSubject();
        // 登录了返回true
        if (subject.isAuthenticated()) {
            return new ResponseBean(HttpStatus.OK.value(), "您已经登录了(You are already logged in)", null);
        } else {
            return new ResponseBean(HttpStatus.OK.value(), "你是游客(You are guest)", null);
        }
    }


    /**
     * 获取指定用户
     * @param userDto
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author dolyw.com
     * @date 2018/8/30 10:42
     */
    @GetMapping("/getDetail")
//    @RequiresPermissions(logical = Logical.AND, value = {"user:view"})
    public ResponseBean findById(UserDto userDto) {
        Integer id = userDto.getUserId();
        User user = userService.selectByPrimaryKey(id);
        if (user == null) {
            throw new CustomException("查询失败(Query Failure)");
        }
        user.setPassword(null);
        return new ResponseBean(HttpStatus.OK.value(), "查询成功(Query was successful)", user);
    }

    /**
     * 通过手机注册
     *
     * @param request
     * @param sms
     * @return
     */
    @PostMapping("/register/sendSMS")
    public ResponseBean addByPhone(HttpServletRequest request, @RequestBody SMS sms) {
        String phone = sms.getPhone();
        Integer min = 3;
        sms.setMin(min);
        sms.setTemplateId(1109982);
        if (phone == null && phone.equals("")) {
            throw new CustomUnauthorizedException("号码为空(Phone Null.)");
        }
        User userTemp = new User();
        userTemp.setPhone(phone);
        userTemp = userService.selectOne(userTemp);
        if (userTemp != null && StringUtil.isNotBlank(userTemp.getUserName())) {
            throw new CustomUnauthorizedException("该帐号已存在(Phone exist.)");
        }
        String s = SMSUtil.sendSMS(request, sms);
        return new ResponseBean(HttpStatus.OK.value(), "发送成功(Send Success)", s);
    }

    @PostMapping("/register/checkSMS")
    public ResponseBean check(HttpServletRequest request, @RequestBody SMS sms) {
        SMSUtil.checkSMS(sms);
        //将用户信息存入数据库
        User user = new User();
        user.setPhone(sms.getPhone());
        user.setUserName(sms.getUserName());
        user.setPassword(sms.getPassword());
        user.setRegTime(new Date());
        int count = userUtil.insertNewUser(user);
        if (count <= 0) {
            throw new CustomException("新增失败(Insert Failure)");
        }
        Integer userId = user.getUserId();
        return new ResponseBean(HttpStatus.OK.value(), "新增成功(Send Success)", userId);
    }

    @PostMapping("/addEmployee")
    public ResponseBean addEmployee(@RequestBody Map<String,String> user){
        Integer count = userUtil.addEmployee(user);
        if (count<=0){
            throw new CustomUnauthorizedException("插入失败");
        }
        return new ResponseBean(HttpStatus.OK.value(), "新增成功(Send Success)", count);
    }

    @DeleteMapping("/delete")
    public ResponseBean deleteEmployee(@RequestParam Integer userId){
        Integer count = userUtil.deleteEmployee(userId);
        if (count<=0){
            throw new CustomUnauthorizedException("删除失败");
        }
        return new ResponseBean(HttpStatus.OK.value(), "删除成功(Delete Success)", null);
    }

    /**
     * 更新用户
     * @param userDto
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author dolyw.com
     */
    @PutMapping("/updateBaseDate")
    public ResponseBean updateBase(@RequestBody UserDto userDto) {
        UserDto userDtoTemp = new UserDto();
        userDtoTemp.setUserId(userDto.getUserId());
        int count = userService.selectCount(userDtoTemp);
        if (count<=0) {
            throw new CustomUnauthorizedException("该帐号不存在(Account not exist.)");
        }
        count = userService.updateByPrimaryKeySelective(userUtil.getBaseUser(userDto));
        if (count <= 0) {
            throw new CustomException("更新失败(Update Failure)");
        }
        return new ResponseBean(HttpStatus.OK.value(), "更新成功(Update Success)", null);
    }

    @PutMapping("/updatePassword")
    public ResponseBean updatePassword(@RequestBody Map<String,Object> userDate){
        if (!userDate.containsKey("userId")){
            throw new CustomException("更新失败(Update Failure)");
        }
        String oldPassword = userDate.get("oldPassword").toString();
        String newPassword = userDate.get("newPassword").toString();
        Integer userId = Integer.parseInt(userDate.get("userId").toString());
        User user = userService.selectByPrimaryKey(userId);
        if (!user.getPassword().equals(oldPassword)){
            throw new CustomException("原密码错误! 更新失败(Update Failure)");
        }
        user.setPassword(newPassword);
        Integer count = userService.updateByPrimaryKeySelective(user);
        return new ResponseBean(HttpStatus.OK.value(), "更新成功(Update Success)", null);
    }

    @PutMapping("/updatePhone/sendSMS")
    public ResponseBean updatePhoneS(HttpServletRequest request, @RequestBody SMS sms){
        String phone = sms.getPhone();
        Integer min = 3;
        sms.setMin(min);
        sms.setTemplateId(1109984);
        if(phone==null && phone.equals("")){
            throw new CustomUnauthorizedException("号码为空(Phone Null.)");
        }
        User userTemp = new User();
        userTemp.setPhone(phone);
        Integer count = userService.selectCount(userTemp);
        if (count <= 0) {
            throw new CustomUnauthorizedException("该电话不存在(Phone NotExist.)");
        }
        String s = SMSUtil.sendSMS(request,sms);
        return new ResponseBean(HttpStatus.OK.value(), "发送成功(Send Success)", s);
    }

    @PutMapping("/updatePhone/checkSMS")
    public ResponseBean updatePhoneC(HttpServletRequest request, @RequestBody SMS sms){
        String code = sms.getCode();
        JSONObject json = (JSONObject)request.getSession().getAttribute("MsCode");
        if(!json.getString("Code").equals(code)){
            throw new CustomUnauthorizedException("验证码错误(Code Error.)");
        }
        if((System.currentTimeMillis() - json.getLong("createTime")) > 1000 * 60 * 3){
            throw new CustomUnauthorizedException("验证码过期(Code expire.)");
        }
        //将用户信息存入数据库
        User user = userService.selectByPrimaryKey(sms.getUserId());
        user.setPhone(sms.getPhone());
        int count = userUtil.insertNewUser(user);
        if (count <= 0){
            throw new CustomException("新增失败(Insert Failure)");
        }
        return new ResponseBean(HttpStatus.OK.value(), "新增成功(Send Success)", user);
    }

    /**
     * 删除用户
     *
     * @param id
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author dolyw.com
     * @date 2018/8/30 10:43
     */
//    @DeleteMapping
////    @RequiresPermissions(logical = Logical.AND, value = {"user:edit"})
//    public ResponseBean delete(@RequestParam Integer id) {
//        User user = new User();
//        user.setUserId(id);
//        Integer count = userService.selectCount(user);
//        if (count <= 0) {
//            throw new CustomException("删除失败，账号不存在(Deletion Failed. Account does not exist.)");
//        }
//        count = userService.deleteByPrimaryKey(id);
//        if (count <= 0) {
//            throw new CustomException("删除失败(Deletion Failed)");
//        }
//        return new ResponseBean(HttpStatus.OK.value(), "删除成功(Delete Success)", null);
//    }

}